#include "xtypes.h"
#include "xaux.h"
#include "util_image.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>



bmpfh_t fnBmpFileHeader(DWORD bfSize)
{
	bmpfh_t bmpfh;

	bmpfh.bfType = AUX_MAKEWORD('B','M');
	bmpfh.bfSize = bfSize;
	bmpfh.bfReserved1 = 0;
	bmpfh.bfReserved2 = 0;
	bmpfh.bfOffBits  = sizeof(bmpfh_t)+sizeof(bmpih_t);

	return bmpfh;
}



bmpih_t fnBmpInfoHeader(LONG biWidth, LONG biHeight, WORD biPlanes,	WORD biBitCount)
{
	bmpih_t bmpih;

	bmpih.biSize = sizeof(bmpih_t);
	bmpih.biWidth = biWidth;
	bmpih.biHeight = biHeight;
	bmpih.biPlanes = biPlanes;
	bmpih.biBitCount = biBitCount;
	bmpih.biCompression = 0;
	bmpih.biSizeImage = 0;
	bmpih.biXPelsPerMeter = 0;
	bmpih.biYPelsPerMeter = 0;
	bmpih.biClrImportant = 0;
	bmpih.biClrUsed = 0;

	return bmpih;
}



void LoadCanvasFromBitmap24(CxSphereCanvas& canvas, lpcstr_t lpszPathName)
{
	CxBlob bmpobject(xGetFileLength(lpszPathName));
	bmpfh_t bmpfh;
	bmpih_t bmpih;
	memptr_t iter;
	char* pChannel;
	DWORD dwCr;
	int_t x,y;
	int_t offset;

	bmpobject.bload(lpszPathName);
	iter = bmpobject.data();
	memcpy(&bmpfh, iter, sizeof(bmpfh_t));
	iter += sizeof(bmpfh_t);
	memcpy(&bmpih, iter, sizeof(bmpih_t));
	iter += sizeof(bmpih_t);

	if(bmpih.biBitCount!=24)
		return;

	offset = bmpfh.bfOffBits;
	int_t pitch = DIB_PITCH_BYTES(bmpih.biWidth,3);
	canvas.Resize(bmpih.biWidth, bmpih.biHeight);

	int_t width, height;
	width = bmpih.biWidth;
	height = bmpih.biHeight;

	for(y=0;y<=height-1;y++)
	{
		iter = bmpobject.data() + offset + y*pitch;
		pChannel = (char*)iter;
		for(x=0;x<=width-1;x++)
		{
			dwCr = AUX_MAKEDWORD(pChannel[0], pChannel[1], pChannel[2], 0);
			canvas.SetPixel(x,height-1-y, dwCr);
			pChannel+=3;
		}

	}

	return;
}



void LoadCanvasFromBitmap32(CxSphereCanvas& canvas, lpcstr_t lpszPathName)
{
	CxBlob bmpobject(xGetFileLength(lpszPathName));
	bmpfh_t bmpfh;
	bmpih_t bmpih;
	memptr_t iter;
	DWORD* pCr;
	int_t x,y;
	int_t offset;

	bmpobject.bload(lpszPathName);
	iter = bmpobject.data();
	memcpy(&bmpfh, iter, sizeof(bmpfh_t));
	iter += sizeof(bmpfh_t);
	memcpy(&bmpih, iter, sizeof(bmpih_t));
	iter += sizeof(bmpih_t);

	if(bmpih.biBitCount!=32)
		return;

	offset = bmpfh.bfOffBits;
	int_t pitch = DIB_PITCH_BYTES(bmpih.biWidth,4);
	canvas.Resize(bmpih.biWidth, bmpih.biHeight);

	int_t width, height;
	width = bmpih.biWidth;
	height = bmpih.biHeight;

	for(y=0;y<=height-1;y++)
	{
		iter = bmpobject.data() + offset + y*pitch;
		pCr = (DWORD*)iter;
		for(x=0;x<=width-1;x++)
		{
			canvas.SetPixel(x,height-1-y, pCr[x]);
		}
	}

	return;
}




void SaveCanvasAsBitmap32(lpcstr_t lpszPathName, CxSphereCanvas& canvas)
{
	CxBlob bmpobject;
	bmpfh_t bmpfh;
	bmpih_t bmpih;
	int_t pitch = DIB_PITCH_BYTES(canvas.GetWidth(),4);

	bmpih = fnBmpInfoHeader(canvas.GetWidth(), canvas.GetHeight(), 1, 32);
	bmpfh = fnBmpFileHeader(sizeof(bmpfh_t) + sizeof(bmpih_t) + pitch*canvas.GetHeight());
	bmpobject.resize(bmpfh.bfSize);

	int_t x,y;

	int_t nlength, offset;

	offset = 0;
	nlength = sizeof(bmpfh_t);
	bmpobject.fill_with(offset, &bmpfh, nlength);

	offset += nlength;
	nlength = sizeof(bmpih_t);
	bmpobject.fill_with(offset, &bmpih, nlength);

	offset += nlength;
	int_t width, height;
	width = canvas.GetWidth();
	height = canvas.GetHeight();

	memptr_t iter;
	DWORD* pCr;

	for(y=0;y<=height-1;y++)
	{
		iter = bmpobject.data() + offset + y*pitch;
		pCr = (DWORD*)iter;
		for(x=0;x<=width-1;x++)
		{
			pCr[x] = canvas.GetPixel(x,height-1-y);

		}
	}

	bmpobject.bsave(lpszPathName);

	return;
}

void LoadCanvasFromPCX(CxSphereCanvas& canvas, lpcstr_t lpszPathName)
{

}